<html><head><title>TabPanel.js</title><link rel="stylesheet" type="text/css" href="../resources/style.css" media="screen"/></head><body><h1>TabPanel.js</h1><pre class="highlighted"><code><i>/**
 * @class Ext.TabPanel
 * &lt;p&gt;A basic tab container. TabPanels can be used exactly like a standard {@link Ext.Panel} <b>for</b> layout
 * purposes, but also have special support <b>for</b> containing child Components that are managed using a CardLayout
 * layout manager, and displayed as seperate tabs.
 * &lt;/p&gt;
 * &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; TabPanels use their {@link Ext.Panel#header header} or {@link Ext.Panel#footer footer} element
 * (depending on the {@link #tabPosition} configuration) to accommodate the tab selector buttons. This means that a TabPanel
 * will not display any configured title, and will not display any configured header {@link Ext.Panel#tools tools}.
 * To display a header, embed the TabPanel <b>in</b> a {@link Ext.Panel Panel} which uses
 * &lt;b&gt;&lt;tt&gt;{@link Ext.Container#layout layout: <em>'fit'</em>}&lt;/tt&gt;&lt;/b&gt;.
 * &lt;/p&gt;
 * &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; It is advisable to configure all child items of a TabPanel (and any Container which uses a CardLayout) <b>with</b>
 * &lt;b&gt;&lt;tt&gt;{@link Ext.Component#hideMode hideMode: <em>'offsets'</em>}&lt;/tt&gt;&lt;/b&gt; to avoid rendering errors <b>in</b> child components hidden
 * using the CSS &lt;tt&gt;display&lt;/tt&gt; style.
 * &lt;/p&gt;
 * &lt;p&gt;There is no actual tab class &amp;mdash; each tab is simply a {@link Ext.BoxComponent Component} such
 * as a {@link Ext.Panel Panel}. However, when rendered <b>in</b> a TabPanel, each child Component can fire
 * additional events that only exist <b>for</b> tabs and are not available from other Component. These are:
 * &lt;/p&gt;
 * &lt;ul&gt;
 * &lt;li&gt;&lt;b&gt;activate&lt;/b&gt;: Fires when <b>this</b> Component becomes the active tab.
 * &lt;div class=&quot;mdetail-params&quot;&gt;
 *      &lt;strong style=&quot;font-weight: normal;&quot;&gt;Listeners will be called <b>with</b> the following arguments:&lt;/strong&gt;
 *      &lt;ul&gt;&lt;li&gt;&lt;code&gt;tab&lt;/code&gt; : Panel&lt;div class=&quot;sub-desc&quot;&gt;The tab that was activated&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
 *  &lt;/div&gt;&lt;/li&gt;
 * &lt;li&gt;&lt;b&gt;deactivate&lt;/b&gt;: Fires when the Component that was the active tab becomes deactivated.
 * &lt;div class=&quot;mdetail-params&quot;&gt;
 *      &lt;strong style=&quot;font-weight: normal;&quot;&gt;Listeners will be called <b>with</b> the following arguments:&lt;/strong&gt;
 *      &lt;ul&gt;&lt;li&gt;&lt;code&gt;tab&lt;/code&gt; : Panel&lt;div class=&quot;sub-desc&quot;&gt;The tab that was deactivated&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
 *  &lt;/div&gt;&lt;/li&gt;
 * &lt;/ul&gt;
 * &lt;p&gt;To add Components to a TabPanel which are generated dynamically on the server, it is necessary to
 * create a server script to generate the Javascript to create the Component required.&lt;/p&gt;
 * For example, to add a GridPanel to a TabPanel where the GridPanel is generated by the server
 * based on certain parameters, you would need to execute an Ajax request to invoke your the script,
 * and process the response object to add it to the TabPanel:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
Ext.Ajax.request({
    url: <em>'gen-invoice-grid.php'</em>,
    params: {
        startDate : Ext.getCmp(<em>'start-date'</em>).getValue(),
        endDate : Ext.getCmp(<em>'end-date'</em>).getValue()
    },
    success: <b>function</b>(xhr) {
        <b>var</b> newComponent = eval(xhr.responseText);
        myTabPanel.add(newComponent);
        myTabPanel.setActiveTab(newComponent);
    },
    failure: <b>function</b>() {
        Ext.Msg.alert(&quot;Grid create failed&quot;, &quot;Server communication failure&quot;);
    }
});
&lt;/code&gt;&lt;/pre&gt;
 * &lt;p&gt;The server script would need to <b>return</b> an executable Javascript statement which, when processed
 * using &lt;tt&gt;eval()&lt;/tt&gt; will <b>return</b> either a config object <b>with</b> an {@link Ext.Component#xtype xtype},
 * or an instantiated Component. For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
(<b>function</b>() {
    <b>function</b> formatDate(value){
        <b>return</b> value ? value.dateFormat(<em>'M d, Y'</em>) : <em>''</em>;
    };

    <b>var</b> store = <b>new</b> Ext.data.Store({
        url: <em>'get-invoice-data.php'</em>,
        baseParams: {
            startDate: <em>'01/01/2008'</em>,
            endDate: <em>'01/31/2008'</em>
        },
        reader: <b>new</b> Ext.data.JsonReader({
            record: <em>'transaction'</em>,
            id: <em>'id'</em>,
            totalRecords: <em>'total'</em>
        }, [
           <em>'customer'</em>,
           <em>'invNo'</em>,
           {name: <em>'date'</em>, type: <em>'date'</em>, dateFormat: <em>'m/d/Y'</em>},
           {name: <em>'value'</em>, type: <em>'float'</em>}
        ])
    });

    <b>var</b> grid = <b>new</b> Ext.grid.GridPanel({
        title: <em>'Invoice Report'</em>,
        bbar: <b>new</b> Ext.PagingToolbar(store),
        store: store,
        columns: [
            {header: &quot;Customer&quot;, width: 250, dataIndex: <em>'customer'</em>, sortable: true},
            {header: &quot;Invoice Number&quot;, width: 120, dataIndex: <em>'invNo'</em>, sortable: true},
            {header: &quot;Invoice Date&quot;, width: 100, dataIndex: <em>'date'</em>, renderer: formatDate, sortable: true},
            {header: &quot;Value&quot;, width: 120, dataIndex: <em>'value'</em>, renderer: <em>'usMoney'</em>, sortable: true}
        ],
    });
    store.load();
    <b>return</b> grid;
})();
&lt;/code&gt;&lt;/pre&gt;
 * &lt;p&gt;Since that code is &lt;i&gt;generated&lt;/i&gt; by a server script, the &lt;tt&gt;baseParams&lt;/tt&gt; <b>for</b> the Store
 * can be configured into the Store. The metadata to allow generation of the Record layout, and the
 * ColumnModel is also known on the server, so these can be generated into the code.&lt;/p&gt;
 * &lt;p&gt;When that code fragment is passed through the &lt;tt&gt;eval&lt;/tt&gt; <b>function</b> in the success handler
 * of the Ajax request, the code is executed by the Javascript processor, and the anonymous <b>function</b>
 * runs, and returns the grid.&lt;/p&gt;
 * &lt;p&gt;There are several other methods available <b>for</b> creating TabPanels. The output of the following
 * examples should produce exactly the same appearance. The tabs can be created and rendered completely
 * <b>in</b> code, as <b>in</b> this example:&lt;/p&gt;
 * &lt;pre&gt;&lt;code&gt;
<b>var</b> tabs = <b>new</b> Ext.TabPanel({
    renderTo: Ext.getBody(),
    activeTab: 0,
    items: [{
        title: <em>'Tab 1'</em>,
        html: <em>'A simple tab'</em>
    },{
        title: <em>'Tab 2'</em>,
        html: <em>'Another one'</em>
    }]
});
&lt;/code&gt;&lt;/pre&gt;
  * &lt;p&gt;TabPanels can also be rendered from pre-existing markup <b>in</b> a couple of ways.  See the {@link #autoTabs} example <b>for</b>
  * rendering entirely from markup that is already structured correctly as a TabPanel (a container div <b>with</b>
  * one or more nested tab divs <b>with</b> class <em>'x-tab'</em>). You can also render from markup that is not strictly
  * structured by simply specifying by id which elements should be the container and the tabs. Using <b>this</b> method,
  * tab content can be pulled from different elements within the page by id regardless of page structure.  Note
  * that the tab divs <b>in</b> this example contain the class <em>'x-hide-display'</em> so that they can be rendered deferred
  * without displaying outside the tabs. You could alternately set {@link #deferredRender} to false to render all
  * content tabs on page load. For example:
  * &lt;pre&gt;&lt;code&gt;
<b>var</b> tabs = <b>new</b> Ext.TabPanel({
    renderTo: <em>'my-tabs'</em>,
    activeTab: 0,
    items:[
        {contentEl:<em>'tab1'</em>, title:<em>'Tab 1'</em>},
        {contentEl:<em>'tab2'</em>, title:<em>'Tab 2'</em>}
    ]
});

<i>// Note that the tabs <b>do</b> not have to be nested within the container (although they can be)</i>
&amp;lt;div id=&quot;my-tabs&quot;&gt;&amp;lt;/div&gt;
&amp;lt;div id=&quot;tab1&quot; class=&quot;x-hide-display&quot;&gt;A simple tab&amp;lt;/div&gt;
&amp;lt;div id=&quot;tab2&quot; class=&quot;x-hide-display&quot;&gt;Another one&amp;lt;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
 * @extends Ext.Panel
 * @constructor
 * @param {Object} config The configuration options
 */</i>
Ext.TabPanel = Ext.extend(Ext.Panel,  {
    <i>/**
     * @cfg {Boolean} layoutOnTabChange Set to true to <b>do</b> a layout of tab items as tabs are changed.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {String} tabCls &lt;b&gt;This config option is used on &lt;u&gt;child Components&lt;/u&gt; of ths TabPanel.&lt;/b&gt; A CSS
     * class name applied to the tab strip item representing the child Component, allowing special
     * styling to be applied.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Boolean} monitorResize True to automatically monitor window resize events and rerender the layout on
     * browser resize (defaults to true).
     */</i>
    monitorResize : true,
    <i>/**
     * @cfg {Boolean} deferredRender Internally, the TabPanel uses a {@link Ext.layout.CardLayout} to manage its tabs.
     * This property will be passed on to the layout as its {@link Ext.layout.CardLayout#deferredRender} config value,
     * determining whether or not each tab is rendered only when first accessed (defaults to true).
     * &lt;p&gt;Be aware that leaving deferredRender as &lt;b&gt;&lt;tt&gt;true&lt;/tt&gt;&lt;/b&gt; means that, <b>if</b> the TabPanel is within
     * a {@link Ext.form.FormPanel form}, then until a tab is activated, any Fields within that tab will not
     * be rendered, and will therefore not be submitted and will not be available to either
     * {@link Ext.form.BasicForm#getValues getValues} or {@link Ext.form.BasicForm#setValues setValues}.&lt;/p&gt;
     */</i>
    deferredRender : true,
    <i>/**
     * @cfg {Number} tabWidth The initial width <b>in</b> pixels of each <b>new</b> tab (defaults to 120).
     */</i>
    tabWidth: 120,
    <i>/**
     * @cfg {Number} minTabWidth The minimum width <b>in</b> pixels <b>for</b> each tab when {@link #resizeTabs} = true (defaults to 30).
     */</i>
    minTabWidth: 30,
    <i>/**
     * @cfg {Boolean} resizeTabs True to automatically resize each tab so that the tabs will completely fill the
     * tab strip (defaults to false).  Setting <b>this</b> to true may cause specific widths that might be set per tab to
     * be overridden <b>in</b> order to fit them all into view (although {@link #minTabWidth} will always be honored).
     */</i>
    resizeTabs:false,
    <i>/**
     * @cfg {Boolean} enableTabScroll True to enable scrolling to tabs that may be invisible due to overflowing the
     * overall TabPanel width. Only available <b>with</b> tabPosition:<em>'top'</em> (defaults to false).
     */</i>
    enableTabScroll: false,
    <i>/**
     * @cfg {Number} scrollIncrement The number of pixels to scroll each time a tab scroll button is pressed (defaults
     * to 100, or <b>if</b> {@link #resizeTabs} = true, the calculated tab width).  Only applies when {@link #enableTabScroll} = true.
     */</i>
    scrollIncrement : 0,
    <i>/**
     * @cfg {Number} scrollRepeatInterval Number of milliseconds between each scroll <b>while</b> a tab scroll button is
     * continuously pressed (defaults to 400).
     */</i>
    scrollRepeatInterval : 400,
    <i>/**
     * @cfg {Float} scrollDuration The number of milliseconds that each scroll animation should last (defaults to .35).
     * Only applies when {@link #animScroll} = true.
     */</i>
    scrollDuration : .35,
    <i>/**
     * @cfg {Boolean} animScroll True to animate tab scrolling so that hidden tabs slide smoothly into view (defaults
     * to true).  Only applies when {@link #enableTabScroll} = true.
     */</i>
    animScroll : true,
    <i>/**
     * @cfg {String} tabPosition The position where the tab strip should be rendered (defaults to <em>'top'</em>).  The only
     * other supported value is <em>'bottom'</em>.  Note that tab scrolling is only supported <b>for</b> position <em>'top'</em>.
     */</i>
    tabPosition: <em>'top'</em>,
    <i>/**
     * @cfg {String} baseCls The base CSS class applied to the panel (defaults to <em>'x-tab-panel'</em>).
     */</i>
    baseCls: <em>'x-tab-panel'</em>,
    <i>/**
     * @cfg {Boolean} autoTabs
     * &lt;p&gt;True to query the DOM <b>for</b> any divs <b>with</b> a class of <em>'x-tab'</em> to be automatically converted
     * to tabs and added to <b>this</b> panel (defaults to false).  Note that the query will be executed within the scope of
     * the container element only (so that multiple tab panels from markup can be supported via <b>this</b> method).&lt;/p&gt;
     * &lt;p&gt;This method is only possible when the markup is structured correctly as a container <b>with</b> nested
     * divs containing the class <em>'x-tab'</em>. To create TabPanels without these limitations, or to pull tab content from
     * other elements on the page, see the example at the top of the class <b>for</b> generating tabs from markup.&lt;/p&gt;
     * &lt;p&gt;There are a couple of things to note when using <b>this</b> method:&lt;ul&gt;
     * &lt;li&gt;When using the autoTabs config (as opposed to passing individual tab configs <b>in</b> the TabPanel's
     * {@link #items} collection), you must use {@link #applyTo} to correctly use the specified id as the tab container.
     * The autoTabs method &lt;em&gt;replaces&lt;/em&gt; existing content <b>with</b> the TabPanel components.&lt;/li&gt;
     * &lt;li&gt;Make sure that you set {@link #deferredRender} to false so that the content elements <b>for</b> each tab will be
     * rendered into the TabPanel immediately upon page load, otherwise they will not be transformed until each tab
     * is activated and will be visible outside the TabPanel.&lt;/li&gt;
     * &lt;/ul&gt;Example usage:&lt;/p&gt;
     * &lt;pre&gt;&lt;code&gt;
<b>var</b> tabs = <b>new</b> Ext.TabPanel({
    applyTo: <em>'my-tabs'</em>,
    activeTab: 0,
    deferredRender: false,
    autoTabs: true
});

<i>// This markup will be converted to a TabPanel from the code above</i>
&amp;lt;div id=&quot;my-tabs&quot;&gt;
    &amp;lt;div class=&quot;x-tab&quot; title=&quot;Tab 1&quot;&gt;A simple tab&amp;lt;/div&gt;
    &amp;lt;div class=&quot;x-tab&quot; title=&quot;Tab 2&quot;&gt;Another one&amp;lt;/div&gt;
&amp;lt;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
     */</i>
    autoTabs : false,
    <i>/**
     * @cfg {String} autoTabSelector The CSS selector used to search <b>for</b> tabs <b>in</b> existing markup when {@link #autoTabs}
     * = true (defaults to <em>'div.x-tab'</em>).  This can be any valid selector supported by {@link Ext.DomQuery#select}.
     * Note that the query will be executed within the scope of <b>this</b> tab panel only (so that multiple tab panels from
     * markup can be supported on a page).
     */</i>
    autoTabSelector:<em>'div.x-tab'</em>,
    <i>/**
     * @cfg {String/Number} activeTab A string id or the numeric index of the tab that should be initially
     * activated on render (defaults to none).
     */</i>
    activeTab : null,
    <i>/**
     * @cfg {Number} tabMargin The number of pixels of space to calculate into the sizing and scrolling of tabs. If you
     * change the margin <b>in</b> CSS, you will need to update <b>this</b> value so calculations are correct <b>with</b> either resizeTabs
     * or scrolling tabs. (defaults to 2)
     */</i>
    tabMargin : 2,
    <i>/**
     * @cfg {Boolean} plain True to render the tab strip without a background container image (defaults to false).
     */</i>
    plain: false,
    <i>/**
     * @cfg {Number} wheelIncrement For scrolling tabs, the number of pixels to increment on mouse wheel scrolling (defaults to 20).
     */</i>
    wheelIncrement : 20,

    <i>/*
     * This is a protected property used when concatenating tab ids to the TabPanel id <b>for</b> internal uniqueness.
     * It does not generally need to be changed, but can be <b>if</b> external code also uses an id scheme that can
     * potentially clash <b>with</b> this one.
     */</i>
    idDelimiter : <em>'__'</em>,

    <i>// private</i>
    itemCls : <em>'x-tab-item'</em>,

    <i>// private config overrides</i>
    elements: <em>'body'</em>,
    headerAsText: false,
    frame: false,
    hideBorders:true,

    <i>// private</i>
    initComponent : <b>function</b>(){
        <b>this</b>.frame = false;
        Ext.TabPanel.superclass.initComponent.call(<b>this</b>);
        <b>this</b>.addEvents(
            <i>/**
             * @event beforetabchange
             * Fires before the active tab changes. Handlers can <b>return</b> false to cancel the tab change.
             * @param {TabPanel} <b>this</b>
             * @param {Panel} newTab The tab being activated
             * @param {Panel} currentTab The current active tab
             */</i>
            <em>'beforetabchange'</em>,
            <i>/**
             * @event tabchange
             * Fires after the active tab has changed.
             * @param {TabPanel} <b>this</b>
             * @param {Panel} tab The <b>new</b> active tab
             */</i>
            <em>'tabchange'</em>,
            <i>/**
             * @event contextmenu
             * Relays the contextmenu event from a tab selector element <b>in</b> the tab strip.
             * @param {TabPanel} <b>this</b>
             * @param {Panel} tab The target tab
             * @param {EventObject} e
             */</i>
            <em>'contextmenu'</em>
        );
        <b>this</b>.setLayout(<b>new</b> Ext.layout.CardLayout({
            deferredRender: <b>this</b>.deferredRender
        }));
        <b>if</b>(this.tabPosition == <em>'top'</em>){
            <b>this</b>.elements += <em>',header'</em>;
            <b>this</b>.stripTarget = <em>'header'</em>;
        }<b>else</b> {
            <b>this</b>.elements += <em>',footer'</em>;
            <b>this</b>.stripTarget = <em>'footer'</em>;
        }
        <b>if</b>(!<b>this</b>.stack){
            <b>this</b>.stack = Ext.TabPanel.AccessStack();
        }
        <b>this</b>.initItems();
    },

    <i>// private</i>
    render : <b>function</b>(){
        Ext.TabPanel.superclass.render.apply(<b>this</b>, arguments);
        <b>if</b>(this.activeTab !== undefined){
            <b>var</b> item = <b>this</b>.activeTab;
            <b>delete</b> this.activeTab;
            <b>this</b>.setActiveTab(item);
        }
    },

    <i>// private</i>
    onRender : <b>function</b>(ct, position){
        Ext.TabPanel.superclass.onRender.call(<b>this</b>, ct, position);

        <b>if</b>(this.plain){
            <b>var</b> pos = <b>this</b>.tabPosition == <em>'top'</em> ? <em>'header'</em> : <em>'footer'</em>;
            <b>this</b>[pos].addClass(<em>'x-tab-panel-'</em>+pos+<em>'-plain'</em>);
        }

        <b>var</b> st = <b>this</b>[this.stripTarget];

        <b>this</b>.stripWrap = st.createChild({cls:<em>'x-tab-strip-wrap'</em>, cn:{
            tag:<em>'ul'</em>, cls:<em>'x-tab-strip x-tab-strip-'</em>+<b>this</b>.tabPosition}});

        <b>var</b> beforeEl = (<b>this</b>.tabPosition==<em>'bottom'</em> ? <b>this</b>.stripWrap : null);
        <b>this</b>.stripSpacer = st.createChild({cls:<em>'x-tab-strip-spacer'</em>}, beforeEl);
        <b>this</b>.strip = <b>new</b> Ext.Element(<b>this</b>.stripWrap.dom.firstChild);

        <b>this</b>.edge = <b>this</b>.strip.createChild({tag:<em>'li'</em>, cls:<em>'x-tab-edge'</em>});
        <b>this</b>.strip.createChild({cls:<em>'x-clear'</em>});

        <b>this</b>.body.addClass(<em>'x-tab-panel-body-'</em>+<b>this</b>.tabPosition);

        <b>if</b>(!<b>this</b>.itemTpl){
            <b>var</b> tt = <b>new</b> Ext.Template(
                 <em>'&lt;li class=&quot;{cls}&quot; id=&quot;{id}&quot;&gt;&lt;a class=&quot;x-tab-strip-close&quot; onclick=&quot;<b>return</b> false;&quot;&gt;&lt;/a&gt;'</em>,
                 <em>'&lt;a class=&quot;x-tab-right&quot; href=&quot;#&quot; onclick=&quot;<b>return</b> false;&quot;&gt;&lt;em class=&quot;x-tab-left&quot;&gt;'</em>,
                 <em>'&lt;span class=&quot;x-tab-strip-inner&quot;&gt;&lt;span class=&quot;x-tab-strip-text {iconCls}&quot;&gt;{text}&lt;/span&gt;&lt;/span&gt;'</em>,
                 <em>'&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;'</em>
            );
            tt.disableFormats = true;
            tt.compile();
            Ext.TabPanel.prototype.itemTpl = tt;
        }

        <b>this</b>.items.each(<b>this</b>.initTab, <b>this</b>);
    },

    <i>// private</i>
    afterRender : <b>function</b>(){
        Ext.TabPanel.superclass.afterRender.call(<b>this</b>);
        <b>if</b>(this.autoTabs){
            <b>this</b>.readTabs(false);
        }
    },

    <i>// private</i>
    initEvents : <b>function</b>(){
        Ext.TabPanel.superclass.initEvents.call(<b>this</b>);
        <b>this</b>.on(<em>'add'</em>, <b>this</b>.onAdd, <b>this</b>);
        <b>this</b>.on(<em>'remove'</em>, <b>this</b>.onRemove, <b>this</b>);

        <b>this</b>.strip.on(<em>'mousedown'</em>, <b>this</b>.onStripMouseDown, <b>this</b>);
        <b>this</b>.strip.on(<em>'contextmenu'</em>, <b>this</b>.onStripContextMenu, <b>this</b>);
        <b>if</b>(this.enableTabScroll){
            <b>this</b>.strip.on(<em>'mousewheel'</em>, <b>this</b>.onWheel, <b>this</b>);
        }
    },

    <i>// private</i>
    findTargets : <b>function</b>(e){
        <b>var</b> item = null;
        <b>var</b> itemEl = e.getTarget(<em>'li'</em>, <b>this</b>.strip);
        <b>if</b>(itemEl){
            item = <b>this</b>.getComponent(itemEl.id.split(<b>this</b>.idDelimiter)[1]);
            <b>if</b>(item.disabled){
                <b>return</b> {
                    close : null,
                    item : null,
                    el : null
                };
            }
        }
        <b>return</b> {
            close : e.getTarget(<em>'.x-tab-strip-close'</em>, <b>this</b>.strip),
            item : item,
            el : itemEl
        };
    },

    <i>// private</i>
    onStripMouseDown : <b>function</b>(e){
        <b>if</b>(e.button != 0){
            <b>return</b>;
        }
        e.preventDefault();
        <b>var</b> t = <b>this</b>.findTargets(e);
        <b>if</b>(t.close){
            <b>this</b>.remove(t.item);
            <b>return</b>;
        }
        <b>if</b>(t.item &amp;&amp; t.item != <b>this</b>.activeTab){
            <b>this</b>.setActiveTab(t.item);
        }
    },

    <i>// private</i>
    onStripContextMenu : <b>function</b>(e){
        e.preventDefault();
        <b>var</b> t = <b>this</b>.findTargets(e);
        <b>if</b>(t.item){
            <b>this</b>.fireEvent(<em>'contextmenu'</em>, <b>this</b>, t.item, e);
        }
    },

    <i>/**
     * True to scan the markup <b>in</b> this tab panel <b>for</b> autoTabs using the autoTabSelector
     * @param {Boolean} removeExisting True to remove existing tabs
     */</i>
    readTabs : <b>function</b>(removeExisting){
        <b>if</b>(removeExisting === true){
            <b>this</b>.items.each(<b>function</b>(item){
                <b>this</b>.remove(item);
            }, <b>this</b>);
        }
        <b>var</b> tabs = <b>this</b>.el.query(<b>this</b>.autoTabSelector);
        <b>for</b>(var i = 0, len = tabs.length; i &lt; len; i++){
            <b>var</b> tab = tabs[i];
            <b>var</b> title = tab.getAttribute(<em>'title'</em>);
            tab.removeAttribute(<em>'title'</em>);
            <b>this</b>.add({
                title: title,
                contentEl: tab
            });
        }
    },

    <i>// private</i>
    initTab : <b>function</b>(item, index){
        <b>var</b> before = <b>this</b>.strip.dom.childNodes[index];
        <b>var</b> cls = item.closable ? <em>'x-tab-strip-closable'</em> : <em>''</em>;
        <b>if</b>(item.disabled){
            cls += <em>' x-item-disabled'</em>;
        }
        <b>if</b>(item.iconCls){
            cls += <em>' x-tab-<b>with</b>-icon'</em>;
        }
        <b>if</b>(item.tabCls){
            cls += <em>' '</em> + item.tabCls;
        }

        <b>var</b> p = {
            id: <b>this</b>.id + <b>this</b>.idDelimiter + item.getItemId(),
            text: item.title,
            cls: cls,
            iconCls: item.iconCls || <em>''</em>
        };
        <b>var</b> el = before ?
                 <b>this</b>.itemTpl.insertBefore(before, p) :
                 <b>this</b>.itemTpl.append(<b>this</b>.strip, p);

        Ext.fly(el).addClassOnOver(<em>'x-tab-strip-over'</em>);

        <b>if</b>(item.tabTip){
            Ext.fly(el).child(<em>'span.x-tab-strip-text'</em>, true).qtip = item.tabTip;
        }
        item.tabEl = el;

        item.on(<em>'disable'</em>, <b>this</b>.onItemDisabled, <b>this</b>);
        item.on(<em>'enable'</em>, <b>this</b>.onItemEnabled, <b>this</b>);
        item.on(<em>'titlechange'</em>, <b>this</b>.onItemTitleChanged, <b>this</b>);
        item.on(<em>'iconchange'</em>, <b>this</b>.onItemIconChanged, <b>this</b>);
        item.on(<em>'beforeshow'</em>, <b>this</b>.onBeforeShowItem, <b>this</b>);
    },

    <i>// private</i>
    onAdd : <b>function</b>(tp, item, index){
        <b>this</b>.initTab(item, index);
        <b>if</b>(this.items.getCount() == 1){
            <b>this</b>.syncSize();
        }
        <b>this</b>.delegateUpdates();
    },

    <i>// private</i>
    onBeforeAdd : <b>function</b>(item){
        <b>var</b> existing = item.events ? (<b>this</b>.items.containsKey(item.getItemId()) ? item : null) : <b>this</b>.items.get(item);
        <b>if</b>(existing){
            <b>this</b>.setActiveTab(item);
            <b>return</b> false;
        }
        Ext.TabPanel.superclass.onBeforeAdd.apply(<b>this</b>, arguments);
        <b>var</b> es = item.elements;
        item.elements = es ? es.replace(<em>',header'</em>, <em>''</em>) : es;
        item.border = (item.border === true);
    },

    <i>// private</i>
    onRemove : <b>function</b>(tp, item){
        Ext.destroy(Ext.get(<b>this</b>.getTabEl(item)));
        <b>this</b>.stack.remove(item);
        item.un(<em>'disable'</em>, <b>this</b>.onItemDisabled, <b>this</b>);
        item.un(<em>'enable'</em>, <b>this</b>.onItemEnabled, <b>this</b>);
        item.un(<em>'titlechange'</em>, <b>this</b>.onItemTitleChanged, <b>this</b>);
        item.un(<em>'iconchange'</em>, <b>this</b>.onItemIconChanged, <b>this</b>);
        item.un(<em>'beforeshow'</em>, <b>this</b>.onBeforeShowItem, <b>this</b>);
        <b>if</b>(item == <b>this</b>.activeTab){
            <b>var</b> next = <b>this</b>.stack.next();
            <b>if</b>(next){
                <b>this</b>.setActiveTab(next);
            }<b>else</b> if(<b>this</b>.items.getCount() &gt; 0){
                <b>this</b>.setActiveTab(0);
            }<b>else</b>{
                <b>this</b>.activeTab = null;
            }
        }
        <b>this</b>.delegateUpdates();
    },

    <i>// private</i>
    onBeforeShowItem : <b>function</b>(item){
        <b>if</b>(item != <b>this</b>.activeTab){
            <b>this</b>.setActiveTab(item);
            <b>return</b> false;
        }
    },

    <i>// private</i>
    onItemDisabled : <b>function</b>(item){
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>if</b>(el){
            Ext.fly(el).addClass(<em>'x-item-disabled'</em>);
        }
        <b>this</b>.stack.remove(item);
    },

    <i>// private</i>
    onItemEnabled : <b>function</b>(item){
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>if</b>(el){
            Ext.fly(el).removeClass(<em>'x-item-disabled'</em>);
        }
    },

    <i>// private</i>
    onItemTitleChanged : <b>function</b>(item){
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>if</b>(el){
            Ext.fly(el).child(<em>'span.x-tab-strip-text'</em>, true).innerHTML = item.title;
        }
    },
    
    <i>//private</i>
    onItemIconChanged: <b>function</b>(item, iconCls, oldCls){
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>if</b>(el){
            Ext.fly(el).child(<em>'span.x-tab-strip-text'</em>).replaceClass(oldCls, iconCls);
        }
    },

    <i>/**
     * Gets the DOM element <b>for</b> tab strip item which activates the
     * child panel <b>with</b> the specified ID. Access <b>this</b> to change the visual treatment of the
     * item, <b>for</b> example by changing the CSS class name.
     * @param {Panel/Number} tab The tab component, or the tab's index
     * @<b>return</b> {HTMLElement} The DOM node
     */</i>
    getTabEl : <b>function</b>(item){
        <b>var</b> itemId = (<b>typeof</b> item === <em>'number'</em>)?<b>this</b>.items.items[item].getItemId() : item.getItemId();
        <b>return</b> document.getElementById(<b>this</b>.id+<b>this</b>.idDelimiter+itemId);
    },

    <i>// private</i>
    onResize : <b>function</b>(){
        Ext.TabPanel.superclass.onResize.apply(<b>this</b>, arguments);
        <b>this</b>.delegateUpdates();
    },

    <i>/**
     * Suspends any internal calculations or scrolling <b>while</b> doing a bulk operation. See {@link #endUpdate}
     */</i>
    beginUpdate : <b>function</b>(){
        <b>this</b>.suspendUpdates = true;
    },

    <i>/**
     * Resumes calculations and scrolling at the end of a bulk operation. See {@link #beginUpdate}
     */</i>
    endUpdate : <b>function</b>(){
        <b>this</b>.suspendUpdates = false;
        <b>this</b>.delegateUpdates();
    },

    <i>/**
     * Hides the tab strip item <b>for</b> the passed tab
     * @param {Number/String/Panel} item The tab index, id or item
     */</i>
    hideTabStripItem : <b>function</b>(item){
        item = <b>this</b>.getComponent(item);
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>if</b>(el){
            el.style.display = <em>'none'</em>;
            <b>this</b>.delegateUpdates();
        }
        <b>this</b>.stack.remove(item);
    },

    <i>/**
     * Unhides the tab strip item <b>for</b> the passed tab
     * @param {Number/String/Panel} item The tab index, id or item
     */</i>
    unhideTabStripItem : <b>function</b>(item){
        item = <b>this</b>.getComponent(item);
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>if</b>(el){
            el.style.display = <em>''</em>;
            <b>this</b>.delegateUpdates();
        }
    },

    <i>// private</i>
    delegateUpdates : <b>function</b>(){
        <b>if</b>(this.suspendUpdates){
            <b>return</b>;
        }
        <b>if</b>(this.resizeTabs &amp;&amp; <b>this</b>.rendered){
            <b>this</b>.autoSizeTabs();
        }
        <b>if</b>(this.enableTabScroll &amp;&amp; <b>this</b>.rendered){
            <b>this</b>.autoScrollTabs();
        }
    },

    <i>// private</i>
    autoSizeTabs : <b>function</b>(){
        <b>var</b> count = <b>this</b>.items.length;
        <b>var</b> ce = <b>this</b>.tabPosition != <em>'bottom'</em> ? <em>'header'</em> : <em>'footer'</em>;
        <b>var</b> ow = <b>this</b>[ce].dom.offsetWidth;
        <b>var</b> aw = <b>this</b>[ce].dom.clientWidth;

        <b>if</b>(!<b>this</b>.resizeTabs || count &lt; 1 || !aw){ <i>// !aw <b>for</b> display:none</i>
            <b>return</b>;
        }

        <b>var</b> each = Math.max(Math.min(Math.floor((aw-4) / count) - <b>this</b>.tabMargin, <b>this</b>.tabWidth), <b>this</b>.minTabWidth); <i>// -4 <b>for</b> float errors <b>in</b> IE</i>
        <b>this</b>.lastTabWidth = each;
        <b>var</b> lis = <b>this</b>.stripWrap.dom.getElementsByTagName(<em>'li'</em>);
        <b>for</b>(var i = 0, len = lis.length-1; i &lt; len; i++) { <i>// -1 <b>for</b> the &quot;edge&quot; li</i>
            <b>var</b> li = lis[i];
            <b>var</b> inner = li.childNodes[1].firstChild.firstChild;
            <b>var</b> tw = li.offsetWidth;
            <b>var</b> iw = inner.offsetWidth;
            inner.style.width = (each - (tw-iw)) + <em>'px'</em>;
        }
    },

    <i>// private</i>
    adjustBodyWidth : <b>function</b>(w){
        <b>if</b>(this.header){
            <b>this</b>.header.setWidth(w);
        }
        <b>if</b>(this.footer){
            <b>this</b>.footer.setWidth(w);
        }
        <b>return</b> w;
    },

    <i>/**
     * Sets the specified tab as the active tab. This method fires the {@link #beforetabchange} event which
     * can <b>return</b> false to cancel the tab change.
     * @param {String/Panel} tab The id or tab Panel to activate
     */</i>
    setActiveTab : <b>function</b>(item){
        item = <b>this</b>.getComponent(item);
        <b>if</b>(!item || <b>this</b>.fireEvent(<em>'beforetabchange'</em>, <b>this</b>, item, <b>this</b>.activeTab) === false){
            <b>return</b>;
        }
        <b>if</b>(!<b>this</b>.rendered){
            <b>this</b>.activeTab = item;
            <b>return</b>;
        }
        <b>if</b>(this.activeTab != item){
            <b>if</b>(this.activeTab){
                <b>var</b> oldEl = <b>this</b>.getTabEl(<b>this</b>.activeTab);
                <b>if</b>(oldEl){
                    Ext.fly(oldEl).removeClass(<em>'x-tab-strip-active'</em>);
                }
                <b>this</b>.activeTab.fireEvent(<em>'deactivate'</em>, <b>this</b>.activeTab);
            }
            <b>var</b> el = <b>this</b>.getTabEl(item);
            Ext.fly(el).addClass(<em>'x-tab-strip-active'</em>);
            <b>this</b>.activeTab = item;
            <b>this</b>.stack.add(item);

            <b>this</b>.layout.setActiveItem(item);
            <b>if</b>(this.layoutOnTabChange &amp;&amp; item.doLayout){
                item.doLayout();
            }
            <b>if</b>(this.scrolling){
                <b>this</b>.scrollToTab(item, <b>this</b>.animScroll);
            }

            item.fireEvent(<em>'activate'</em>, item);
            <b>this</b>.fireEvent(<em>'tabchange'</em>, <b>this</b>, item);
        }
    },

    <i>/**
     * Gets the currently active tab.
     * @<b>return</b> {Panel} The active tab
     */</i>
    getActiveTab : <b>function</b>(){
        <b>return</b> this.activeTab || null;
    },

    <i>/**
     * Gets the specified tab by id.
     * @param {String} id The tab id
     * @<b>return</b> {Panel} The tab
     */</i>
    getItem : <b>function</b>(item){
        <b>return</b> this.getComponent(item);
    },

    <i>// private</i>
    autoScrollTabs : <b>function</b>(){
        <b>this</b>.pos = <b>this</b>.tabPosition==<em>'bottom'</em> ? <b>this</b>.footer : <b>this</b>.header;
        <b>var</b> count = <b>this</b>.items.length;
        <b>var</b> ow = <b>this</b>.pos.dom.offsetWidth;
        <b>var</b> tw = <b>this</b>.pos.dom.clientWidth;

        <b>var</b> wrap = <b>this</b>.stripWrap;
        <b>var</b> wd = wrap.dom;
        <b>var</b> cw = wd.offsetWidth;
        <b>var</b> pos = <b>this</b>.getScrollPos();
        <b>var</b> l = <b>this</b>.edge.getOffsetsTo(<b>this</b>.stripWrap)[0] + pos;

        <b>if</b>(!<b>this</b>.enableTabScroll || count &lt; 1 || cw &lt; 20){ <i>// 20 to prevent display:none issues</i>
            <b>return</b>;
        }
        <b>if</b>(l &lt;= tw){
            wd.scrollLeft = 0;
            wrap.setWidth(tw);
            <b>if</b>(this.scrolling){
                <b>this</b>.scrolling = false;
                <b>this</b>.pos.removeClass(<em>'x-tab-scrolling'</em>);
                <b>this</b>.scrollLeft.hide();
                <b>this</b>.scrollRight.hide();
                <i>// See here: http://extjs.com/forum/showthread.php?t=49308&amp;highlight=isSafari</i>
                <b>if</b>(Ext.isAir || Ext.isWebKit){
                    wd.style.marginLeft = <em>''</em>;
                    wd.style.marginRight = <em>''</em>;
                }
            }
        }<b>else</b>{
            <b>if</b>(!<b>this</b>.scrolling){
                <b>this</b>.pos.addClass(<em>'x-tab-scrolling'</em>);
                <i>// See here: http://extjs.com/forum/showthread.php?t=49308&amp;highlight=isSafari</i>
                <b>if</b>(Ext.isAir || Ext.isWebKit){
                    wd.style.marginLeft = <em>'18px'</em>;
                    wd.style.marginRight = <em>'18px'</em>;
                }
            }
            tw -= wrap.getMargins(<em>'lr'</em>);
            wrap.setWidth(tw &gt; 20 ? tw : 20);
            <b>if</b>(!<b>this</b>.scrolling){
                <b>if</b>(!<b>this</b>.scrollLeft){
                    <b>this</b>.createScrollers();
                }<b>else</b>{
                    <b>this</b>.scrollLeft.show();
                    <b>this</b>.scrollRight.show();
                }
            }
            <b>this</b>.scrolling = true;
            <b>if</b>(pos &gt; (l-tw)){ <i>// ensure it stays within bounds</i>
                wd.scrollLeft = l-tw;
            }<b>else</b>{ <i>// otherwise, make sure the active tab is still visible</i>
                <b>this</b>.scrollToTab(<b>this</b>.activeTab, false);
            }
            <b>this</b>.updateScrollButtons();
        }
    },

    <i>// private</i>
    createScrollers : <b>function</b>(){
        <b>this</b>.pos.addClass(<em>'x-tab-scrolling-'</em> + <b>this</b>.tabPosition);
        <b>var</b> h = <b>this</b>.stripWrap.dom.offsetHeight;

        <i>// left</i>
        <b>var</b> sl = <b>this</b>.pos.insertFirst({
            cls:<em>'x-tab-scroller-left'</em>
        });
        sl.setHeight(h);
        sl.addClassOnOver(<em>'x-tab-scroller-left-over'</em>);
        <b>this</b>.leftRepeater = <b>new</b> Ext.util.ClickRepeater(sl, {
            interval : <b>this</b>.scrollRepeatInterval,
            handler: <b>this</b>.onScrollLeft,
            scope: <b>this</b>
        });
        <b>this</b>.scrollLeft = sl;

        <i>// right</i>
        <b>var</b> sr = <b>this</b>.pos.insertFirst({
            cls:<em>'x-tab-scroller-right'</em>
        });
        sr.setHeight(h);
        sr.addClassOnOver(<em>'x-tab-scroller-right-over'</em>);
        <b>this</b>.rightRepeater = <b>new</b> Ext.util.ClickRepeater(sr, {
            interval : <b>this</b>.scrollRepeatInterval,
            handler: <b>this</b>.onScrollRight,
            scope: <b>this</b>
        });
        <b>this</b>.scrollRight = sr;
    },

    <i>// private</i>
    getScrollWidth : <b>function</b>(){
        <b>return</b> this.edge.getOffsetsTo(<b>this</b>.stripWrap)[0] + <b>this</b>.getScrollPos();
    },

    <i>// private</i>
    getScrollPos : <b>function</b>(){
        <b>return</b> parseInt(<b>this</b>.stripWrap.dom.scrollLeft, 10) || 0;
    },

    <i>// private</i>
    getScrollArea : <b>function</b>(){
        <b>return</b> parseInt(<b>this</b>.stripWrap.dom.clientWidth, 10) || 0;
    },

    <i>// private</i>
    getScrollAnim : <b>function</b>(){
        <b>return</b> {duration:<b>this</b>.scrollDuration, callback: <b>this</b>.updateScrollButtons, scope: <b>this</b>};
    },

    <i>// private</i>
    getScrollIncrement : <b>function</b>(){
        <b>return</b> this.scrollIncrement || (<b>this</b>.resizeTabs ? <b>this</b>.lastTabWidth+2 : 100);
    },

    <i>/**
     * Scrolls to a particular tab <b>if</b> tab scrolling is enabled
     * @param {Panel} item The item to scroll to
     * @param {Boolean} animate True to enable animations
     */</i>

    scrollToTab : <b>function</b>(item, animate){
        <b>if</b>(!item){ <b>return</b>; }
        <b>var</b> el = <b>this</b>.getTabEl(item);
        <b>var</b> pos = <b>this</b>.getScrollPos(), area = <b>this</b>.getScrollArea();
        <b>var</b> left = Ext.fly(el).getOffsetsTo(<b>this</b>.stripWrap)[0] + pos;
        <b>var</b> right = left + el.offsetWidth;
        <b>if</b>(left &lt; pos){
            <b>this</b>.scrollTo(left, animate);
        }<b>else</b> if(right &gt; (pos + area)){
            <b>this</b>.scrollTo(right - area, animate);
        }
    },

    <i>// private</i>
    scrollTo : <b>function</b>(pos, animate){
        <b>this</b>.stripWrap.scrollTo(<em>'left'</em>, pos, animate ? <b>this</b>.getScrollAnim() : false);
        <b>if</b>(!animate){
            <b>this</b>.updateScrollButtons();
        }
    },

    onWheel : <b>function</b>(e){
        <b>var</b> d = e.getWheelDelta()*<b>this</b>.wheelIncrement*-1;
        e.stopEvent();

        <b>var</b> pos = <b>this</b>.getScrollPos();
        <b>var</b> newpos = pos + d;
        <b>var</b> sw = <b>this</b>.getScrollWidth()-<b>this</b>.getScrollArea();

        <b>var</b> s = Math.max(0, Math.min(sw, newpos));
        <b>if</b>(s != pos){
            <b>this</b>.scrollTo(s, false);
        }
    },

    <i>// private</i>
    onScrollRight : <b>function</b>(){
        <b>var</b> sw = <b>this</b>.getScrollWidth()-<b>this</b>.getScrollArea();
        <b>var</b> pos = <b>this</b>.getScrollPos();
        <b>var</b> s = Math.min(sw, pos + <b>this</b>.getScrollIncrement());
        <b>if</b>(s != pos){
            <b>this</b>.scrollTo(s, <b>this</b>.animScroll);
        }
    },

    <i>// private</i>
    onScrollLeft : <b>function</b>(){
        <b>var</b> pos = <b>this</b>.getScrollPos();
        <b>var</b> s = Math.max(0, pos - <b>this</b>.getScrollIncrement());
        <b>if</b>(s != pos){
            <b>this</b>.scrollTo(s, <b>this</b>.animScroll);
        }
    },

    <i>// private</i>
    updateScrollButtons : <b>function</b>(){
        <b>var</b> pos = <b>this</b>.getScrollPos();
        <b>this</b>.scrollLeft[pos == 0 ? <em>'addClass'</em> : <em>'removeClass'</em>](<em>'x-tab-scroller-left-disabled'</em>);
        <b>this</b>.scrollRight[pos &gt;= (<b>this</b>.getScrollWidth()-<b>this</b>.getScrollArea()) ? <em>'addClass'</em> : <em>'removeClass'</em>](<em>'x-tab-scroller-right-disabled'</em>);
    },

    <i>// private</i>
    beforeDestroy : <b>function</b>() {
        <b>if</b>(this.items){
            <b>this</b>.items.each(<b>function</b>(item){
                <b>if</b>(item &amp;&amp; item.tabEl){
                    Ext.get(item.tabEl).removeAllListeners();
                    item.tabEl = null;
                }
            }, <b>this</b>);
        }
        <b>if</b>(this.strip){
            <b>this</b>.strip.removeAllListeners();
        }
        Ext.TabPanel.superclass.beforeDestroy.apply(<b>this</b>);
    }

    <i>/**
     * @cfg {Boolean} collapsible
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {String} header
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Boolean} headerAsText
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @property header
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @property title
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Array} tools
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Boolean} hideCollapseTool
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Boolean} titleCollapse
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Boolean} collapsed
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {String} layout
     * @hide
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Object} layoutConfig
     * @hide
     */</i>

});
Ext.reg(<em>'tabpanel'</em>, Ext.TabPanel);

<i>/**
 * Sets the specified tab as the active tab. This method fires the {@link #beforetabchange} event which
 * can <b>return</b> false to cancel the tab change.
 * @param {String/Panel} tab The id or tab Panel to activate
 * @method activate
 */</i>
Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;

<i>// private utility class used by TabPanel</i>
Ext.TabPanel.AccessStack = <b>function</b>(){
    <b>var</b> items = [];
    <b>return</b> {
        add : <b>function</b>(item){
            items.push(item);
            <b>if</b>(items.length &gt; 10){
                items.shift();
            }
        },

        remove : <b>function</b>(item){
            <b>var</b> s = [];
            <b>for</b>(var i = 0, len = items.length; i &lt; len; i++) {
                <b>if</b>(items[i] != item){
                    s.push(items[i]);
                }
            }
            items = s;
        },

        next : <b>function</b>(){
            <b>return</b> items.pop();
        }
    };
};

</code></pre><hr><div style="font-size:10px;text-align:center;color:gray;">Ext - Copyright &copy; 2006-2007 Ext JS, LLC<br />All rights reserved.</div>
    </body></html>